/****************************************************************
*  * *Process the common configure interface
*  * *
*  * *file name:logfile.cpp
*  * *
*  * *Copyright (C)2012 Cisco webex.
*  * *All rights reserved
*  * *
*  * *Author:zhenye
*  * *Date  :2013-04-27
*  * *
*  * ****************************************************************/

#include <string>
#include "mct_system.h"

#include "log4cpp/PropertyConfigurator.hh"
#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/BasicLayout.hh"

#include "errcode.h"
#include "logfile.h"
#include "logmgr.h"

CLogger* CLogger::m_pInstance = NULL;

CLogger::CLogger()
{
    m_bInit = BOOL_FALSE;
}

CLogger::~CLogger(void)
{
    try
    {
        log4cpp::Category::shutdown();
    }
    catch(std::runtime_error &f)
    {
        std::cout << "Configure problem " << f.what() << std::endl;
    }
}

LONG CLogger::initiation(std::string &strConfigFile)
{
    LONG oldmask = MCT_umask(0026);


    /* get config value */
    CHAR szConfigPath[MAX_ABSOLUTE_PATH_LEN] = {0};
    GetProgramPath(0, szConfigPath, MAX_ABSOLUTE_PATH_LEN - 1);
    std::string strConfigPathTemp = szConfigPath;
    strConfigPathTemp.append(strConfigFile);

    try
    {
        log4cpp::PropertyConfigurator::configure(strConfigPathTemp);
        log4cpp::Category& oFileAppender = log4cpp::Category::getRoot();
    }
    catch(std::runtime_error &f)
    {
        std::cout << "Configure problem " << f.what() << std::endl;
        MCT_umask(oldmask);
        return ERR_INIT_LOG_MRG;
    }

    m_bInit = BOOL_TRUE;
    MCT_umask(oldmask);
    return ERR_COMMON_SUCCEED;
}

CLogger* CLogger::getInstance(std::string &strConfigFile)
{
    if (!m_pInstance)
    {
        m_pInstance = new CLogger();
        LONG ret = m_pInstance->initiation(strConfigFile);
        if (ERR_COMMON_SUCCEED != ret)
        {
            std::cout << "Failed to call initiation() "<< std::endl;
            delete m_pInstance;
            m_pInstance = NULL;
        }
    }

    return m_pInstance;
}

CLogger* CLogger::getInstance()
{
    return m_pInstance;
}

VOID CLogger::setPriority(LONG logLevel)
{
    if (BOOL_TRUE != m_bInit)
    {
        std::cout << "Can not set priority for logger not initiation." << std::endl;
        return;
    }

    LONG oldmask = MCT_umask(0026);

    try
    {
        log4cpp::Category& oFileAppender = log4cpp::Category::getRoot();

        switch (logLevel)
        {
            case LOG_CRITICAL:
            {
                oFileAppender.setPriority(log4cpp::Priority::CRIT);
                break;
            }
            case LOG_ERROR:
            {
                oFileAppender.setPriority(log4cpp::Priority::ERROR);
                break;
            }
            case LOG_WARN:
            {
                oFileAppender.setPriority(log4cpp::Priority::WARN);
                break;
            }
            case LOG_INFO:
            {
                oFileAppender.setPriority(log4cpp::Priority::INFO);
                break;
            }
            default:
            {
                oFileAppender.setPriority(log4cpp::Priority::DEBUG);
                break;
            }
        }
    }
    catch(std::runtime_error &f)
    {
        std::cout << "set priority problem " << f.what() << std::endl;
    }

    MCT_umask(oldmask);

    return;
}


VOID CLogger::outMsg( const std::string& strInfo, LONG logLevel)
{
    if (BOOL_TRUE != m_bInit)
    {
        std::cout << "Can not output message for logger not initiation." << std::endl;
        return;
    }

    LONG oldmask = MCT_umask(0026);

    try
    {
        log4cpp::Category& oFileAppender = log4cpp::Category::getRoot();
        switch (logLevel)
        {
            case LOG_CRITICAL:
            {
                oFileAppender.crit(strInfo);
                break;
            }
            case LOG_ERROR:
            {
                oFileAppender.error(strInfo);
                break;
            }
            case LOG_WARN:
            {
                oFileAppender.warn(strInfo);
                break;
            }
            case LOG_INFO:
            {
                oFileAppender.info(strInfo);
                break;
            }
            default:
            {
                oFileAppender.debug(strInfo);
                break;
            }
        }
    }
    catch(std::runtime_error &f)
    {
        std::cout << "Configure problem " << f.what() << std::endl;
    }

    MCT_umask(oldmask);

    return;
}
